package com.cvte.boe.media.player;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.Toast;

import com.cvte.boe.media.R;
import com.cvte.boe.media.controller.MediaFileManager;
import com.cvte.boe.media.dao.MediaSettingDao;
import com.cvte.boe.media.dao.MediaSettingDaoImpl;
import com.cvte.boe.media.model.LocalMediaInfo;
import com.cvte.boe.media.utils.LogUtil;
import com.cvte.boe.media.utils.SettingUtil;
import com.cvte.boe.media.utils.constant.Constant;
import com.cvte.boe.media.views.AutoHideLayout;
import com.cvte.boe.media.views.widget.MarqueeTextView;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import pl.droidsonroids.gif.GifDrawable;
import pl.droidsonroids.gif.GifImageView;

/**
 * Created by wuguitong on 2018/4/19.
 */
public class ImagePlayer {
    private static final int MSG_LOOP_SHOW_IMAGE = 0;
    private static final int MSG_UPDATE_IMAGE = 1;
    private static final int MSG_IMAGE_DAMAGED = 2;
    private static final int SECOND = 1000;
    private static final int MINUTE = 60 * SECOND;
    private static final long GIF_SIZE_LIMIT = 4L * 1024 * 1024;
    private long mLoopTime;
    private ImageView mIVShowView;
    private GifImageView mGifImageView;
    private SettingUtil.ILOOP mLoop;
    private SettingUtil.ILOOPTIMER mTimer;
    private Context mContext;
    private String mCurrentFileName;
    private int mCurrentFileIndex;
    private List<LocalMediaInfo> mLocalMediaInfoList;
    private Bitmap mBitmap;
    private DecodeImageThread mDecodeImageThread;
    private MarqueeTextView mTVName;
    private AutoHideLayout ahTopBar;
    private AutoHideLayout ahBottomBar;
    private int mScreenWidth = 0;
    private int mScreenHeight = 0;
    private GifDrawable gifDrawable = null;
    private Handler imageHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case MSG_UPDATE_IMAGE:
                    LocalMediaInfo localMediaInfo = mLocalMediaInfoList.get(mCurrentFileIndex);
                    mIVShowView.setImageBitmap(mBitmap);
                    if(isGifImage(mCurrentFileName)){
                        if(localMediaInfo.getFileSize() <= GIF_SIZE_LIMIT) {
                            try {
                                if(gifDrawable != null){
                                    gifDrawable.stop();
                                    gifDrawable.recycle();
                                }
                                gifDrawable = new GifDrawable(localMediaInfo.getFileAllName());
                                mGifImageView.setImageDrawable(gifDrawable);
                                mGifImageView.setVisibility(View.VISIBLE);
                                gifDrawable.start();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }else{
                            Toast.makeText(mContext,mContext.getString(R.string.gif_file_too_large),Toast.LENGTH_SHORT).show();
                        }
                    }else{
                        if(gifDrawable != null){
                            gifDrawable.stop();
                            gifDrawable.recycle();
                        }
                        mGifImageView.setVisibility(View.GONE);
                    }
                    mTVName.setText(localMediaInfo.getFileName());
                    if(mLoop == SettingUtil.ILOOP.ON){
                        imageHandler.removeMessages(MSG_LOOP_SHOW_IMAGE);
                        imageHandler.sendEmptyMessageDelayed(MSG_LOOP_SHOW_IMAGE,mLoopTime);
                    }
                    break;
                case MSG_LOOP_SHOW_IMAGE:
                    showNextImage();
                    break;
                case MSG_IMAGE_DAMAGED:
                    Toast.makeText(mContext,mLocalMediaInfoList.get(mCurrentFileIndex).getFileName() + " " +mContext.getString(R.string.image_damaged),Toast.LENGTH_SHORT).show();
                    break;
                default:
                    break;
            }
        }
    };

    public ImagePlayer() {
    }
    public void initPlayer(Context context, ImageView imageView, GifImageView gifImageView, MarqueeTextView tvName, AutoHideLayout ahTopBar, AutoHideLayout ahBottomBar, String dir, String fileName, SettingUtil.ILOOP loop, SettingUtil.ILOOPTIMER timer){
        this.mContext = context;
        this.mIVShowView = imageView;
        this.mGifImageView = gifImageView;
        this.mTVName = tvName;
        this.ahBottomBar = ahBottomBar;
        this.ahTopBar = ahTopBar;
        this.mLocalMediaInfoList = new ArrayList<>();
        this.mLocalMediaInfoList.addAll(MediaFileManager.getInstance().getMediaFilesByType(dir, Constant.MediaType.IMAGE));
        this.mCurrentFileName = fileName;
        this.mLoop = loop;
        this.mTimer = timer;
        WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        mScreenWidth = wm.getDefaultDisplay().getWidth();
        mScreenHeight = wm.getDefaultDisplay().getHeight();
        initImageLoopTime(timer);
        mCurrentFileIndex = -1;
        int index = 0;
        for(LocalMediaInfo m : mLocalMediaInfoList){
            if(m.getFileAllName().equals(mCurrentFileName)){
                mCurrentFileIndex = index;
                break;
            }
            index++;
        }
        if((mLocalMediaInfoList.size()) > 0 && (mCurrentFileIndex == -1)) {
            mCurrentFileIndex = 0;
            mCurrentFileName = mLocalMediaInfoList.get(mCurrentFileIndex).getFileAllName();
        }
        mDecodeImageThread = new DecodeImageThread();
        mDecodeImageThread.start();
        showBar();
    }
    private void initImageLoopTime(SettingUtil.ILOOPTIMER timer){
        switch (timer){
            case SEC_5:
                mLoopTime = SECOND * 5;
                break;
            case SEC_10:
                mLoopTime = SECOND * 10;
                break;
            case SEC_20:
                mLoopTime = SECOND * 20;
                break;
            case SEC_30:
                mLoopTime = SECOND * 30;
                break;
            case MIN_1:
                mLoopTime = MINUTE * 1;
                break;
            case MIN_2:
                mLoopTime = MINUTE * 2;
                break;
            case MIN_5:
                mLoopTime = MINUTE * 5;
                break;
            case MIN_10:
                mLoopTime = MINUTE * 10;
                break;
            case MIN_30:
                mLoopTime = MINUTE * 30;
                break;
            case MIN_60:
                mLoopTime = MINUTE * 60;
                break;
            case MIN_120:
                mLoopTime = MINUTE * 120;
                break;
            default:
                break;
        }
    }
    public void setImageLoop(SettingUtil.ILOOP loop){
        if(mLoop != loop) {
            mLoop = loop;
            if(mLoop == SettingUtil.ILOOP.OFF){
                imageHandler.removeMessages(MSG_LOOP_SHOW_IMAGE);
            }else{
                imageHandler.sendEmptyMessageDelayed(MSG_LOOP_SHOW_IMAGE,mLoopTime);
            }
        }
    }
    public void setImageLoopTimer(SettingUtil.ILOOPTIMER timer){
        if(mTimer != timer) {
            mTimer = timer;
            initImageLoopTime(mTimer);
            if(mLoop == SettingUtil.ILOOP.ON){
                imageHandler.removeMessages(MSG_LOOP_SHOW_IMAGE);
                imageHandler.sendEmptyMessageDelayed(MSG_LOOP_SHOW_IMAGE,mLoopTime);
            }
        }
    }
    public void deinitPlayer(){
        imageHandler.removeMessages(MSG_IMAGE_DAMAGED);
        imageHandler.removeMessages(MSG_UPDATE_IMAGE);
        imageHandler.removeMessages(MSG_LOOP_SHOW_IMAGE);
    }
    public boolean showNextImage(){
        if(mDecodeImageThread != null && !mDecodeImageThread.isAlive()){
            mCurrentFileIndex++;
            if(mCurrentFileIndex == mLocalMediaInfoList.size()){
                mCurrentFileIndex = 0;
            }
            mCurrentFileName = mLocalMediaInfoList.get(mCurrentFileIndex).getFileAllName();
            mDecodeImageThread = new DecodeImageThread();
            mDecodeImageThread.start();
            if(mLoop == SettingUtil.ILOOP.ON){
                imageHandler.removeMessages(MSG_LOOP_SHOW_IMAGE);
                imageHandler.sendEmptyMessageDelayed(MSG_LOOP_SHOW_IMAGE,mLoopTime);
            }
            return true;
        }else{
            return false;
        }
    }
    public boolean showPreImage(){
        if(mDecodeImageThread != null && !mDecodeImageThread.isAlive()){
            mCurrentFileIndex--;
            if(mCurrentFileIndex < 0){
                mCurrentFileIndex = mLocalMediaInfoList.size() -1 ;
            }
            mCurrentFileName = mLocalMediaInfoList.get(mCurrentFileIndex).getFileAllName();
            mDecodeImageThread = new DecodeImageThread();
            mDecodeImageThread.start();
            if(mLoop == SettingUtil.ILOOP.ON){
                imageHandler.removeMessages(MSG_LOOP_SHOW_IMAGE);
                imageHandler.sendEmptyMessageDelayed(MSG_LOOP_SHOW_IMAGE,mLoopTime);
            }
            return true;
        }else{
            return false;
        }
    }
    public void showBar(){
        ahBottomBar.show();
        ahTopBar.show();
    }
    private class DecodeImageThread extends Thread{
        @Override
        public void run() {
            if(mBitmap != null && mBitmap.isRecycled()){
                mBitmap.recycle();
            }
            mBitmap = readBitmapAutoSize(mCurrentFileName,mScreenWidth,mScreenHeight);
            if(mBitmap.getWidth() == 0 && mBitmap.getHeight() == 0){
                imageHandler.sendEmptyMessage(MSG_IMAGE_DAMAGED);
            }
            imageHandler.sendEmptyMessage(MSG_UPDATE_IMAGE);
        }
    }
    private BitmapFactory.Options setBitmapOption(String file, int width, int height) {
        BitmapFactory.Options opt = new BitmapFactory.Options();
        opt.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(file, opt);

        float outWidth = opt.outWidth;
        float outHeight = opt.outHeight;

        opt.inDither = false;
        opt.inPreferredConfig = Bitmap.Config.RGB_565;
        opt.inSampleSize = 1;
        float heightRatio = outHeight / height;
        float widthRatio = outWidth / width;
        if (heightRatio > 1 || widthRatio > 1) {

            int sampleSize = (int) Math.ceil(heightRatio > widthRatio ? heightRatio : widthRatio);
            opt.inSampleSize = sampleSize;
        }

        opt.inJustDecodeBounds = false;
        return opt;
    }
    private Bitmap readBitmapAutoSize(String filePath, int outWidth, int outHeight) {
        FileInputStream fs = null;
        BufferedInputStream bs = null;
        try {
            fs = new FileInputStream(filePath);
            bs = new BufferedInputStream(fs);
            BitmapFactory.Options options = setBitmapOption(filePath, outWidth, outHeight);
            return BitmapFactory.decodeStream(bs, null, options);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                bs.close();
                fs.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }
    private boolean isGifImage(String fileName) {
        if (fileName.endsWith(".gif") || fileName.endsWith(".GIF")) {
            return true;
        } else {
            return false;
        }
    }
}
